module Alu (a, b, op, aluout, unsig, compout, overflow);

    // Entradas
	input       [31:0]      a;
	input       [31:0]      b;
	input       [2:0]       op;
	input                   unsig;

	// Saídas
	output      [31:0]      aluout;
	output                  compout;
	output                  overflow;

	reg [31:0] c;
	reg [0:0]  over;
	reg [0:0]  comp;

	assign aluout = c;
	assign overflow = over;
	assign compout = comp;

	always @(a or b or op or unsig) begin

		over = 0;

		// Execute the operation.
		case (op)
			// *** AND ***
			3'b000 : begin
				c = a & b;
			end

			// *** OR ***
			3'b001 : begin
				c = a | b;
			end

			// *** ADD ***
			3'b010 : begin
				c = a + b;
				// Overflow verification.
				if( unsig == 1'b0 ) begin
					if( (a[31] == 1'b0 && b[31] == 1'b0 && c[31] == 1'b1) || (a[31] == 1'b1 && b[31] == 1'b1 && c[31] == 1'b0) ) begin
						over = 1'b1;
					end
				end
			end

			// *** NOR ***
			3'b100 : begin
				c = ~(a | b);
			end

			// *** XOR ***
			3'b101 : begin
				c = a ^ b;
			end

			// *** SUB ***
			3'b110 : begin
				c = a - b;
				// Overflow verification.
				if( unsig == 1'b0 ) begin
					if( (a[31] == 1'b0 && b[31] == 1'b1 && c[31] == 1'b1) || (a[31] == 1'b1 && b[31] == 1'b0 && c[31] == 1'b0) ) begin
						over = 1'b1;
					end
				end
			end

			// No Operation.
			default: begin
			end

		endcase 

        // Refresh compout.
		comp = 1'b0;
		if (unsig == 1'b0) begin
			// If a is negative and b is positive, b > a.
			if (a[31] == 1'b1 && b[31] == 1'b0) begin
				comp = 1'b1;
			end

			// If a is positive and b is positive, we have to compare.
			if (a[31] == 1'b0 && b[31] == 1'b0) begin
				if (a < b) begin
					comp = 1'b1;
				end
			end

            // If both is negative, we have to compare.
			if (a[31] == 1'b1 && b[31] == 1'b1) begin
                // If we negate both in tow complement, the smallest value  
                // will be come the biggest value, vice-versa.
				if ( ~a > ~b) begin
                    comp = 1'b1;
				end
			end
		end

        if (unsig == 1'b1) begin
            if (a < b)
               comp = 1'b1; 
        end

    end // Always.
    
endmodule

